using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Net;
using System.Net.Cache;
using System.Threading;
using System.Windows.Forms;
using HtmlAgilityPack;
using HtmlDocument = HtmlAgilityPack.HtmlDocument;

namespace MangaDownloader
{
    public partial class FormMain : Form
    {
        #region Fields

        private const string StatusFormat = "Status: {0}";

        private const string ScriptUrl1 = "http://blogtruyen.com/js/repa.js";

        private List<string> _listMangaUrl;

        #endregion

        #region Properties

        public List<string> ListMangaUrl
        {
            get { return _listMangaUrl; }
            set { _listMangaUrl = value; }
        }

        #endregion

        public FormMain()
        {
            InitializeComponent();
            ListMangaUrl = new List<string>();
        }

        

        #region Methods

        public static void ShowErrorMessageBox(string message)
        {
            MessageBox.Show(message, "Manga Downloader Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        private void DownloadScript(object obj)
        {
            try
            {
                WebClient client = new WebClient();
                string userAgent = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)";
                client.Headers.Set(HttpRequestHeader.UserAgent, userAgent);
                client.Headers.Set(HttpRequestHeader.ContentType, "gzip");
                client.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
                string fileName = AppDomain.CurrentDomain.BaseDirectory + Path.GetFileName(ScriptUrl1);
                if (File.Exists(fileName)) File.Delete(fileName);
                client.DownloadFileCompleted += client_DownloadFileCompleted;
                client.DownloadFileAsync(new Uri(ScriptUrl1), fileName);
            }
            catch (Exception ex)
            {
                ShowErrorMessageBox(ex.Message);
                if (InvokeRequired)
                    BeginInvoke(new MethodInvoker(Dispose));
                else
                    Dispose();
                return;
            }
        }

        

        #endregion

        #region Events

        private void FormMain_Load(object sender, EventArgs e)
        {
            splitContainer1.Enabled = false;
            lbStatus.Text = string.Format(StatusFormat, "Initial Program");
            progressBar.Visible = true;
            ThreadPool.QueueUserWorkItem(DownloadScript);
        }

        private void cbbMangaSite_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cbbMangaSite.SelectedIndex == 0)
            {
                ListMangaUrl.Clear();
                ListMangaUrl.Add("http://danhmuc.blogtruyen.com");
                ListMangaUrl.Add("http://danhmuc.blogtruyen.com/2010/11/danh-muc-tong-hop-2.html");
                ThreadPool.QueueUserWorkItem(ProcessGetListManga);
            }
        }

        private void ProcessGetListManga(object obj)
        {
            try
            {
                List<Manga> mangas = GetListManga(ListMangaUrl);
                txtSearch.Enabled = true;
                lboxManga.Enabled = true;
                lboxManga.DataSource = mangas;
            }
            catch (Exception ex)
            {
                ShowErrorMessageBox(ex.Message);
            }
        }

        private List<Manga> GetListManga(List<string> listMangaUrl)
        {
            try
            {
//                if(listMangaUrl==null || listMangaUrl.Count==0)
//                {
//                    ShowErrorMessageBox("List Manga Url is null or empty!");
//                    return null;
//                }
                List<Manga> mangas = new List<Manga>();
                foreach (string url in listMangaUrl)
                {
                    HtmlDocument document = GetHtmlDocumentAgility(url);
                    if(document==null) continue;
                    List<Manga> temp = GetListMangaFromBlogTruyen(document);
                    if(temp!=null && temp.Count>0)
                        mangas.AddRange(temp);
                }
                return mangas;
            }
            catch (Exception ex)
            {
                ShowErrorMessageBox(ex.Message);
                return null;
            }
        }

        private List<Manga> GetListMangaFromBlogTruyen(HtmlDocument document)
        {
            try
            {
                List<Manga> mangas = new List<Manga>();
                string xpath = "//table[@class='listing']//tr[@class='bg01' or @class='bg02']";
                HtmlNodeCollection nodeCollection = document.DocumentNode.SelectNodes(xpath);
                if(nodeCollection==null || nodeCollection.Count==0) return null;
                foreach (HtmlNode node in nodeCollection)
                {
                    Manga manga = new Manga();
                    manga.Name = node.ChildNodes[0].InnerText.Trim();
                    manga.Url = node.ChildNodes[0].ChildNodes[0].Attributes["href"].Value;
                    manga.Status = node.ChildNodes[1].InnerText.Trim();
                    mangas.Add(manga);
                }
                return mangas;
            }
            catch (Exception ex)
            {
                ShowErrorMessageBox(ex.Message);
                return null;
            }
        }

        private HtmlDocument GetHtmlDocumentAgility(string url)
        {
            try
            {
                HtmlWeb web = new HtmlWeb();
                HtmlDocument document = web.Load(url);
                return document;
            }
            catch (Exception ex)
            {
                ShowErrorMessageBox(ex.Message);
                return null;
            }
        }

        void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
        {
            try
            {
                if (e.Error != null)
                {
                    ShowErrorMessageBox(e.Error.Message);
                    if (InvokeRequired)
                        BeginInvoke(new MethodInvoker(Dispose));
                    else
                        Dispose();
                    return;
                }
                if (InvokeRequired)
                {
                    BeginInvoke(new MethodInvoker(delegate
                                                      {
                                                          progressBar.Visible = false;
                                                          splitContainer1.Enabled = true;
                                                          lbStatus.Text = string.Format(StatusFormat, "Initial Complete");
                                                      }));
                }
                else
                {
                    progressBar.Visible = false;
                    splitContainer1.Enabled = true;
                    lbStatus.Text = string.Format(StatusFormat, "Initial Complete");
                }
            }
            catch (Exception ex)
            {
                ShowErrorMessageBox(ex.Message);
            }
        }

        #endregion

        

        
    }
}